import Taro from '@tarojs/taro'

export interface VoicePlayerOptions {
  obeyMuteSwitch?: boolean
  volume?: number
  onPlay?: () => void
  onPause?: () => void
  onStop?: () => void
  onEnded?: () => void
  onError?: (error: any) => void
  onTimeUpdate?: (currentTime: number, duration: number) => void
  onCanplay?: () => void
}

export interface VoicePlayerState {
  isPlaying: boolean
  isPaused: boolean
  currentTime: number
  duration: number
  progress: number
  error: string | null
}

export class VoicePlayer {
  private audioContext: any = null
  private options: VoicePlayerOptions
  private state: VoicePlayerState = {
    isPlaying: false,
    isPaused: false,
    currentTime: 0,
    duration: 0,
    progress: 0,
    error: null
  }
  private stateListeners: ((state: VoicePlayerState) => void)[] = []

  constructor(options: VoicePlayerOptions = {}) {
    this.options = {
      obeyMuteSwitch: false,
      volume: 1.0,
      ...options
    }
    this.createAudioContext()
  }

  private createAudioContext() {
    if (this.audioContext) {
      this.destroy()
    }

    try {
      this.audioContext = Taro.createInnerAudioContext()
      console.log('🎵 音频上下文创建成功')
      
      // 配置音频播放器
      this.audioContext.obeyMuteSwitch = this.options.obeyMuteSwitch || false
      this.audioContext.volume = this.options.volume || 1.0
      
      console.log('🔧 音频配置:', {
        obeyMuteSwitch: this.audioContext.obeyMuteSwitch,
        volume: this.audioContext.volume
      })

      // 绑定事件
      this.audioContext.onPlay(() => {
        console.log('▶️ 音频开始播放')
        this.updateState({ isPlaying: true, isPaused: false, error: null })
        this.options.onPlay?.()
      })

      this.audioContext.onPause(() => {
        console.log('⏸️ 音频暂停')
        this.updateState({ isPaused: true, isPlaying: false })
        this.options.onPause?.()
      })

      this.audioContext.onStop(() => {
        console.log('⏹️ 音频停止')
        this.updateState({ 
          isPlaying: false, 
          isPaused: false, 
          currentTime: 0, 
          progress: 0 
        })
        this.options.onStop?.()
      })

      this.audioContext.onEnded(() => {
        console.log('🏁 音频播放结束')
        this.updateState({ 
          isPlaying: false, 
          isPaused: false, 
          currentTime: this.state.duration,
          progress: 100
        })
        this.options.onEnded?.()
      })

      this.audioContext.onError((err: any) => {
        console.error('❌ 音频播放错误:', err)
        const errorMsg = this.getErrorMessage(err)
        this.updateState({ 
          isPlaying: false, 
          isPaused: false, 
          error: errorMsg 
        })
        this.options.onError?.(err)
    })

    this.audioContext.onCanplay(() => {
      const duration = this.audioContext.duration || 0
      console.log('🎵 音频可播放事件触发:', {
        duration: duration,
        src: this.audioContext.src,
        readyState: this.audioContext.readyState
      })
      
      if (duration > 0) {
        this.updateState({ duration })
        console.log('✅ 音频加载完成，时长:', duration)
      } else {
        console.log('⚠️ 音频可播放但时长未获取，尝试重新获取')
        // 延迟再次尝试获取时长
        setTimeout(() => {
          const retryDuration = this.audioContext.duration || 0
          if (retryDuration > 0) {
            console.log('✅ 延迟获取音频时长成功:', retryDuration)
            this.updateState({ duration: retryDuration })
          } else {
            console.log('❌ 延迟获取音频时长失败')
          }
        }, 100)
      }
      this.options.onCanplay?.()
    })

    this.audioContext.onTimeUpdate(() => {
      const currentTime = this.audioContext.currentTime || 0
      const duration = this.audioContext.duration || 0
      
      console.log('⏰ 原始时间更新:', {
        currentTime: currentTime,
        duration: duration,
        src: this.audioContext.src,
        isPlaying: this.audioContext.paused === false
      })
      
      if (duration > 0) {
        const progress = (currentTime / duration) * 100
        this.updateState({ currentTime, duration, progress })
        this.options.onTimeUpdate?.(currentTime, duration)
      } else {
        // 即使duration为0，也尝试更新状态
        console.log('⚠️ 音频时长未获取，但继续更新状态')
        this.updateState({ currentTime, duration, progress: 0 })
        this.options.onTimeUpdate?.(currentTime, duration)
      }
    })
    } catch (error) {
      console.error('创建音频上下文失败:', error)
      const errorMsg = this.getErrorMessage(error)
      this.updateState({ error: errorMsg })
    }
  }

  private updateState(updates: Partial<VoicePlayerState>) {
    this.state = { ...this.state, ...updates }
    this.stateListeners.forEach(listener => listener(this.state))
  }

  private getErrorMessage(error: any): string {
    if (typeof error === 'string') return error
    if (error?.errMsg) return error.errMsg
    if (error?.message) return error.message
    return '播放失败，请重试'
  }

  // 播放语音
  play(src: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (!src) {
        const error = '语音文件地址不能为空'
        this.updateState({ error })
        reject(new Error(error))
        return
      }

      try {
        console.log('🎵 开始播放语音:', {
          src: src,
          isValidUrl: src.startsWith('http'),
          audioContextExists: !!this.audioContext,
          platform: process.env.TARO_ENV
        })

        // 重置状态
        this.updateState({ 
          isPlaying: false, 
          isPaused: false, 
          currentTime: 0, 
          progress: 0, 
          error: null 
        })
        
        // 重新创建音频上下文以确保状态正确
        this.createAudioContext()
        
        // 设置音频源
        this.audioContext.src = src
        console.log('📡 设置音频源:', src)
        
        // 添加加载超时检测
        const loadTimeout = setTimeout(() => {
          console.log('⏰ 音频加载超时，尝试强制播放')
          if (this.audioContext) {
            try {
              this.audioContext.play()
              console.log('✅ 强制播放启动成功')
            } catch (err) {
              console.error('❌ 强制播放失败:', err)
              reject(new Error(`强制播放失败: ${err?.errMsg || err}`))
            }
          } else {
            console.error('❌ 音频上下文为空，无法强制播放')
            reject(new Error('音频上下文为空'))
          }
        }, 3000)
        
        // 监听加载完成，清除超时
        const onCanplayOnce = () => {
          clearTimeout(loadTimeout)
          if (this.audioContext) {
            this.audioContext.offCanplay(onCanplayOnce)
          }
        }
        if (this.audioContext) {
          this.audioContext.onCanplay(onCanplayOnce)
        }
        
        // 开始播放
        if (this.audioContext) {
          try {
            this.audioContext.play()
            console.log('✅ 音频播放启动成功')
            clearTimeout(loadTimeout)
            resolve()
          } catch (err) {
            console.error('❌ 音频播放启动失败:', err)
            clearTimeout(loadTimeout)
            const errorMsg = this.getErrorMessage(err)
            this.updateState({ error: errorMsg })
            reject(err)
          }
        } else {
          console.error('❌ 音频上下文为空，无法开始播放')
          clearTimeout(loadTimeout)
          const errorMsg = '音频上下文未初始化'
          this.updateState({ error: errorMsg })
          reject(new Error(errorMsg))
        }
      } catch (error) {
        const errorMsg = this.getErrorMessage(error)
        this.updateState({ error: errorMsg })
        reject(error)
      }
    })
  }

  // 暂停播放
  pause(): void {
    try {
      if (this.audioContext) {
        this.audioContext.pause()
      } else {
        console.warn('⚠️ 音频上下文为空，无法暂停播放')
      }
    } catch (error) {
      console.error('暂停播放失败:', error)
    }
  }

  // 恢复播放
  resume(): void {
    try {
      if (this.audioContext) {
        this.audioContext.play()
        console.log('✅ 恢复播放成功')
      } else {
        console.warn('⚠️ 音频上下文为空，无法恢复播放')
      }
    } catch (error) {
      console.error('恢复播放失败:', error)
    }
  }

  // 停止播放
  stop(): void {
    try {
      if (this.audioContext) {
        this.audioContext.stop()
      } else {
        console.warn('⚠️ 音频上下文为空，无法停止播放')
      }
    } catch (error) {
      console.error('停止播放失败:', error)
    }
  }

  // 跳转到指定时间
  seek(time: number): void {
    try {
      if (this.audioContext) {
        this.audioContext.seek(time)
      } else {
        console.warn('⚠️ 音频上下文为空，无法跳转播放')
      }
    } catch (error) {
      console.error('跳转播放失败:', error)
    }
  }

  // 跳转到指定进度
  seekToProgress(progress: number): void {
    const time = (progress / 100) * this.state.duration
    this.seek(time)
  }

  // 设置音量
  setVolume(volume: number): void {
    try {
      if (this.audioContext) {
        this.audioContext.volume = Math.max(0, Math.min(1, volume))
      } else {
        console.warn('⚠️ 音频上下文为空，无法设置音量')
      }
    } catch (error) {
      console.error('设置音量失败:', error)
    }
  }

  // 获取当前状态
  getState(): VoicePlayerState {
    return { ...this.state }
  }

  // 获取当前播放时间
  getCurrentTime(): number {
    if (this.audioContext) {
      return this.audioContext.currentTime || 0
    }
    return 0
  }

  // 获取音频总时长
  getDuration(): number {
    if (this.audioContext) {
      return this.audioContext.duration || 0
    }
    return 0
  }

  // 更新选项
  updateOptions(newOptions: VoicePlayerOptions): void {
    this.options = { ...this.options, ...newOptions }
  }

  // 监听状态变化
  onStateChange(listener: (state: VoicePlayerState) => void): () => void {
    this.stateListeners.push(listener)
    
    // 返回取消监听的函数
    return () => {
      const index = this.stateListeners.indexOf(listener)
      if (index > -1) {
        this.stateListeners.splice(index, 1)
      }
    }
  }

  // 销毁播放器
  destroy(): void {
    if (this.audioContext) {
      try {
        this.audioContext.stop()
        this.audioContext.destroy()
      } catch (error) {
        console.error('销毁播放器失败:', error)
      }
      this.audioContext = null
    }
    
    this.stateListeners = []
    this.updateState({
      isPlaying: false,
      isPaused: false,
      currentTime: 0,
      duration: 0,
      progress: 0,
      error: null
    })
  }
}

// 创建全局播放器实例
let globalVoicePlayer: VoicePlayer | null = null

export const getVoicePlayer = (options?: VoicePlayerOptions): VoicePlayer => {
  if (!globalVoicePlayer) {
    globalVoicePlayer = new VoicePlayer(options)
  }
  return globalVoicePlayer
}

export const destroyVoicePlayer = (): void => {
  if (globalVoicePlayer) {
    globalVoicePlayer.destroy()
    globalVoicePlayer = null
  }
}

// 语音播放器管理器
export class VoicePlayerManager {
  private static instance: VoicePlayerManager
  private players: Map<string, VoicePlayer> = new Map()
  private currentPlayer: VoicePlayer | null = null

  static getInstance(): VoicePlayerManager {
    if (!VoicePlayerManager.instance) {
      VoicePlayerManager.instance = new VoicePlayerManager()
    }
    return VoicePlayerManager.instance
  }

  // 获取或创建播放器
  getPlayer(id: string, options?: VoicePlayerOptions): VoicePlayer {
    if (!this.players.has(id)) {
      this.players.set(id, new VoicePlayer(options))
    }
    return this.players.get(id)!
  }

  // 播放语音
  async play(id: string, src: string, options?: VoicePlayerOptions): Promise<void> {
    // 停止当前播放
    if (this.currentPlayer) {
      this.currentPlayer.stop()
    }

    // 获取播放器并设置选项
    const player = this.getPlayer(id, options)
    this.currentPlayer = player

    // 如果提供了新的选项，更新播放器
    if (options) {
      player.updateOptions(options)
    }

    // 播放
    await player.play(src)
  }

  // 停止所有播放
  stopAll(): void {
    this.players.forEach(player => player.stop())
    this.currentPlayer = null
  }

  // 销毁所有播放器
  destroyAll(): void {
    this.players.forEach(player => player.destroy())
    this.players.clear()
    this.currentPlayer = null
  }

  // 获取当前播放器
  getCurrentPlayer(): VoicePlayer | null {
    return this.currentPlayer
  }
}

// 导出管理器实例
export const voicePlayerManager = VoicePlayerManager.getInstance()

// 工具函数
export const formatTime = (seconds: number): string => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins}:${secs.toString().padStart(2, '0')}`
}

export const formatDuration = (seconds: number): string => {
  if (seconds < 60) {
    return `${Math.floor(seconds)}秒`
  } else {
    const mins = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    return `${mins}分${secs}秒`
  }
}

export const validateAudioFile = (file: any): { valid: boolean; error?: string } => {
  if (!file) {
    return { valid: false, error: '文件不存在' }
  }

  const allowedTypes = ['audio/aac', 'audio/mpeg', 'audio/mp4', 'audio/wav', 'audio/amr', 'audio/x-aac']
  if (!allowedTypes.includes(file.type)) {
    return { valid: false, error: '不支持的音频格式' }
  }

  const maxSize = 10 * 1024 * 1024 // 10MB
  if (file.size > maxSize) {
    return { valid: false, error: '文件过大，请选择小于10MB的文件' }
  }

  return { valid: true }
}
